package com.wr.online.test.controller;

import com.wr.online.test.model.vo.RespBean;
import com.wr.online.test.service.IMyService;
import com.wr.online.test.validator.ValidationGroups;
import lombok.Data;
import org.springframework.beans.BeanUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.lang.reflect.Constructor;

/**
 *  数据库实体类CRUD基类接口
 * @param <T> 数据库实体类
 * @param <VO>  后端和前端交互的对象VO
 */
@Data
public abstract class BaseController<T, VO> {

    private Class<?> tClass;    //实体类类型

    public IMyService service;    //对应业务的实现类

    /**
     * 获取单条数据
     *
     * @param id
     * @return
     */
    @GetMapping("/{id}")
//    @ApiOperation("获取单条数据")
    public RespBean getById(@PathVariable Integer id) {
        return service.selectOneById(id);
    }

    /**
     * 新增单条数据
     *
     * @param vo
     * @return
     */
    @PostMapping
//    @ApiOperation("新增单条数据")
    public RespBean post(@Validated(ValidationGroups.Insert.class) @RequestBody VO vo) {
        T newApp = getBean();
        BeanUtils.copyProperties(vo, newApp);
        return service.saveOne(newApp);
    }

    /**
     * 获取批量数据，分页、模糊查询
     *
     * @param vo
     * @return
     */
    @GetMapping
//    @ApiOperation("获取批量数据，分页、模糊查询")
    public RespBean get(@RequestBody VO vo) {
        return service.selectListPage(vo);
    }

    /**
     * 删除指定ID的数据
     *
     * @param id
     * @return
     */
    @DeleteMapping("/{id}")
//    @ApiOperation("删除指定ID的数据")
    public RespBean delete(@PathVariable Integer id) {
        return service.deleteById(id);
    }

    /**
     * 更新单条数据
     *
     * @param vo
     * @return
     */
    @PutMapping("/{id}")
//    @ApiOperation("更新单条数据")
    public RespBean put(@Validated(ValidationGroups.Update.class) @RequestBody VO vo, @PathVariable Integer id) {
        T newApp = getBean();
        BeanUtils.copyProperties(vo, newApp);
        return service.updateOneById(newApp);
    }


    private T getBean() {
        assert tClass != null : "bean类型不能为空";
        Constructor<?> declaredConstructor = null;
        try {
            declaredConstructor = tClass.getDeclaredConstructor();
            return (T) declaredConstructor.newInstance();
        } catch (Exception e) {
//            e.printStackTrace();
            throw new RuntimeException("在创建一个新的"+ tClass.toString() +"实例时出现错误:"+e.getLocalizedMessage());
        }
    }

    public void init(Class<?> tClass,IMyService service){
        setService(service);
        setTClass(tClass);
    }

}